#ifndef _GLANN_H_
#define _GLANN_H_

#include <math.h>
#include <stdlib.h>

#define glann_malloc       malloc
#define glann_free         free

typedef float (*function)(float f);

struct glann_neure_s{ 
    function act_fun;
    function dev_fun;
    float input;
    float output;
    float goal;
};

struct glann_layer_s{
    struct glann_neure_s *neures;
    int nuere_num;
};

struct glann_weight_s{
    float *w;
    int current_layer_num;
    int forward_layer_num;
};

struct glann_network_s{
    int layer_num;
    struct glann_layer_s  *layers;
    struct glann_weight_s *weights;

    float learn_rate;
};


struct glann_iodata_s{
    float *input;
    float *output;
    float *probability;
    int    input_size;
    int    output_size;
};


void  glann_weight_init(struct glann_weight_s *weight);
float glann_weight_get(struct glann_weight_s *weight, int neure_of_current, int neure_of_forward);
void  glann_weight_set(struct glann_weight_s *weight, int neure_of_current, int neure_of_forward, float nw);
float LeakyReLU(float input);
float DevLeakyReLU(float input);
int   glann_network_create(struct glann_network_s *network, unsigned short *layers_describe, int layers_num);
void  glann_network_destory(struct glann_network_s *network);
int   glann_network_run(struct glann_network_s *network, struct glann_iodata_s *dat);
int   glann_network_train(struct glann_network_s *network, struct glann_iodata_s *dat);
int   glann_network_save(struct glann_network_s *network, char *path);
int   glann_network_load(struct glann_network_s *network, char *path);

#endif